package com.kehutong.auth.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.mvc.http.Bean;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.mvc.webservice.WebService;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.util.Enums;
import org.coraframework.util.Objects;
import com.kehutong.auth.dao.UserDao;
import com.kehutong.auth.entity.Account;
import com.kehutong.auth.entity.User;
import com.kehutong.auth.enums.AccountStatus;
import com.kehutong.common.DoveClient;
import com.kehutong.common.enums.Gender;
import com.kehutong.common.util.Token;

/**
 * 账户服务
 * @author: liuzhen
 * @date: 2021-04-10 10:24:32
 */
@WebService("/kht-bin/auth/user")
public class UserService {

    @Inject
    private JdbcSession jdbcSession;
    @Inject
	private UserDao userDao;
    @Inject
	private DoveClient doveClient;

	@ReqMapping("/listPhone")
	public Object listPhone(JSONObject jsonObject){
		JSONArray idArray = jsonObject.getJSONArray("id");
		List<User> list = jdbcSession.findArray(User.class)
									 .in("id", idArray)
									 .eq("deleted", false)
									 .exe();

		Set<String> set = list.stream()
							  .filter(e -> Objects.nonEmpty(e.getMobile()))
							  .map(User::getMobile)
							  .collect(Collectors.toSet());
		return Result.success(set);
	}
    
    @ReqMapping("/list")
    public Object list(JSONObject jsonObject) {
        return jdbcSession.findArray(User.class)
                .eq(jsonObject,  "name","nick_name", "mobile", "email")
                .in(jsonObject, "id")
				.like(jsonObject,"roles")
                .order("createTime", "desc")
                .exe();
    }

	@ReqMapping("/getSuperAdmin")
	public Object getSuperAdmin(JSONObject jsonObject) {
		return jdbcSession.findArray(User.class)
				.findInSet("roles", "5")
				.exe();
	}

    @ReqMapping("/get")
    public Object get(Account account) {
        return account;
    }

	/**
	 * 第三方企业安装应用授权会调用当前方法
	 * 目前默认安装应用人的角色为5(公司管理员权限)有当前公司所有菜单,功能及数据曲
	 */
    @Bean(newInstance = true, copy = true)
	@ReqMapping("/create_user")
	public Object createUser(User item, JSONObject jsonObject) throws Exception {
    	item.setStatus(AccountStatus.ACTIVE);
    	if(Objects.isEmpty(item.getRoles())){
			Set<String> set = new HashSet<>();
			set.add("5");
			item.setRoles(set);
		} else {
    		// 若用户角色包含4则查询企业的相应角色
			if (item.getRoles().contains("4")) {
				JSONObject result = doveClient.post("/admin/service/role/initCorp", (http) -> {
					JSONObject body = new JSONObject();
					body.put("companyNo", item.getCorpNo());
					body.put("companyName", item.getCorpName());
					http.setBody(body.toString());
				});
				item.getRoles().remove("4");
				item.getRoles().add(item.getCorpNo() + "_" + 4);
			}
		}

		String gender = jsonObject.getString("gender");
    	if(Objects.nonEmpty(gender)){
			item.setGender(Enums.getEnum(Gender.class, gender));
		}

		jdbcSession.insert(item);
		
		return item.getId();
	}
	
	@Bean(copy = true)
	@ReqMapping("/change_user")
	public Object changeUser(User item, JSONObject jsonObject) throws Exception {
		String gender = jsonObject.getString("gender");
		if(Objects.nonEmpty(gender)){
			item.setGender(Enums.getEnum(Gender.class, gender));
		}
		item.setStatus(AccountStatus.ACTIVE);
		item.setDeleted(false);
		jdbcSession.updateById(item);
		
		return Result.success();
	}

	@ReqMapping("/updateNames")
	public Object changeUser(JSONObject jsonObject) throws Exception {
		JSONArray users = jsonObject.getJSONArray("users");
		if (users.size() > 0) {
			Map<String, String > idNameMap = new HashMap<>();
			List<String> idList = new ArrayList<>();
			for (int i = 0; i < users.size(); i++) {
				JSONObject eachUser = (JSONObject) users.get(i);
				idNameMap.put(eachUser.getString("id"), eachUser.getString("name"));
				idList.add(eachUser.getString("id"));
			}
			List<User> userList = jdbcSession.findArray(User.class).in("id", idList).exe(false);
			Map<String, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
			List<User> updateUserList = new ArrayList<>();
			for (String each : idList) {
				String name = idNameMap.get(each);
				User user = userMap.get(each);
				if (user != null && !Objects.equal(user.getName(), name)) {
					user.setStatus(AccountStatus.ACTIVE);
					user.setDeleted(false);
					user.setName(name);
					updateUserList.add(user);
				}
			}
			if (updateUserList.size() > 0) {
				jdbcSession.updateById(updateUserList);
			}
		}
		return Result.success();
	}

	@ReqMapping("/get_user")
	public Object getUser(User item) {
		return Result.success(item);
	}
	
	@ReqMapping("/cancel_user")
	public Object cancelUser(User item) throws Exception {
		item.setDeleted(true);
		jdbcSession.updateById(item);
		
		return item.getId();
	}

	@ReqMapping("/get_users")
	public Object getUsers(Token token, JSONObject jsonObject) throws Exception {
		jsonObject.remove("token");

		List<User> users = jdbcSession.findArray(User.class)
				.eq("corpNo", token.getCompanyNo())
				.findInSet("roles", jsonObject.getString("roles"))
				.eq("deleted", false)
				.exe();

		List<String> ids = users.stream().map(User::getId).collect(Collectors.toList());

		if(Objects.nonEmpty(ids)){
			return Result.success(getEmployee(ids));
		}

		return Result.success();
	}

	public JSONArray getEmployee(List<String> ids) throws Exception {
		JSONObject result = doveClient.post("/basic/employee/service/list", http->{
			JSONObject body = new JSONObject();
			body.put("id", ids);

			body.put("pageNo", 1);
			body.put("pageSize", 1000000);

			http.setBody(body.toString());
		});

		JSONArray data = result.getJSONObject("data").getJSONArray("list");

		if (Objects.isNull(data)) {
			return null;
		}

		return data;
	}

	@ReqMapping("/deleteUser")
	public Object deleteUser(String corpNo){
    	List<User> list = jdbcSession.findArray(User.class)
				.eq("corpNo", corpNo)
				.exe();

        jdbcSession.deleteById(list);

		return Result.success();
	}

	@ReqMapping("/updateRolesAdmin")
	public Object updateRolesAdmin(JSONObject jsonObject){

    	try {
			List<User> list = jdbcSession.findArray(User.class).exe();

			Map<String, User> userMap = new HashMap<>();
			list.forEach(item -> {
				userMap.put(item.getLogin_name().toUpperCase(), item);
			});

			Set<String> roles = new HashSet<>();
			roles.add("5");

			JSONArray users = jsonObject.getJSONArray("loginNames");
			List<User> admins = new ArrayList<>();
			users.forEach(item ->{
				String login_name = item.toString();
				User temp = userMap.get(login_name);
				if(Objects.nonNull(temp)){
					temp.setRoles(roles);
					admins.add(temp);
				}
			});

			if(Objects.nonEmpty(admins)){
				jdbcSession.updateById(admins);
			}

		}catch (Exception e){

		}

		return Result.success();
	}

	@ReqMapping("/update_role")
	public Object updateRole(JSONObject jsonObject){
		JSONArray oldEmployees = jsonObject.getJSONArray("oldEmployees");
		if(Objects.nonEmpty(oldEmployees)){
			for (int i = 0; i < oldEmployees.size(); i ++) {
				User user = Pool.get(User.class, oldEmployees.getString(i));
				Set<String> roles = user.getRoles();
				roles.remove(jsonObject.getString("roleId"));
				user.setRoles(roles);
				jdbcSession.updateById(user);
			}
		}

		JSONArray newEmployees = jsonObject.getJSONArray("newEmployees");
		if(Objects.nonEmpty(newEmployees)){
			for (int i = 0; i < newEmployees.size(); i ++) {
				User user = Pool.get(User.class, newEmployees.getString(i));
				if(Objects.isNull(user)){
				  return Result.error(0, "未获取到当前赋权人员账号信息");
                }
				Set<String> roles = user.getRoles();
				if(java.util.Objects.isNull(roles)){
					roles = new HashSet<>();
				}
				roles.add(jsonObject.getString("roleId"));
				user.setRoles(roles);
				jdbcSession.updateById(user);
			}
		}

		return Result.success();
	}
}
